﻿using System;
using System.Linq;
using System.Reflection;
using Config.Keede.Library;
using Keede.RabbitMQ;
using Keede.RabbitMQ.EasyClient;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Keede.Rabbitmq.HandleService
{
    public class TaskHandleController
    {
        readonly HandleServiceConfig _handleServiceConfig;
        readonly IDictionary<string, RabbitmqServer> _serverConfigs;

        public TaskHandleController()
        {
            _handleServiceConfig = ConfigurationManager.GetSection("handleService") as HandleServiceConfig;

            _serverConfigs = new Dictionary<string, RabbitmqServer>();
            var srvs = JsonConvert.DeserializeObject<RabbitmqServerConfig[]>(GetConfig("rabbitmq_server_configs"));
            foreach (var srv in srvs)
            {
                _serverConfigs.Add(srv.Name, srv.RabbitmqServer);
            }
        }

        private string GetConfig(string name)
        {
            var result = ConfManager.GetAppsetting(name);
            if (result == null) throw new NullReferenceException($"{name} 节点未配置");
            return result;
        }

        public void Start()
        {
            foreach (var type in _handleServiceConfig.HandlerTypes)
            {
                var types = Assembly.Load(type.HandlerAssembly).GetTypes().Where(w => w.IsAbstract == false && w.BaseType.Name == typeof(BaseMsgListener<>).Name);
                foreach (var t in types)
                {
                    var obj = Activator.CreateInstance(t);

                    var serverName = obj.GetType().GetProperty("ServerName")?.GetValue(obj);
                    var listener = obj.GetType().GetProperty("Listener")?.GetValue(obj, null) as IQueueListener;

                    if (serverName == null) throw new Exception("MsgListener 中未配置 ServerName 属性值,请在构造函数中对此属性赋值。");
                    if (!_serverConfigs.ContainsKey(serverName.ToString())) throw new Exception($"Msg listener 中配置的服务名称{serverName}在对应的配置文件节点【rabbitmq_server_configs】中未找到！");

                    var server = _serverConfigs[serverName.ToString()];
                    server.Consumer.MqClient.QueueDeclare(listener.QueueName);
                    server.Consumer.MqClient.QueueBind(server.Exchange, listener.QueueName, listener.QueueName);

                    server.Consumer.Subscribe(listener);
                }
            }
        }

        public void Dispose()
        {
            foreach (var server in _serverConfigs)
            {
                server.Value.Consumer.Dispose();
            }
        }
    }
}
